package org.smth.search.query.impl;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import org.apache.lucene.analysis.Token;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.TermQuery;
import org.smth.search.query.QueryAnalyzer;
import org.smth.search.query.QueryInfo;
import org.smth.search.query.QueryParser;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

@Singleton
public class SimpleQueryParser implements QueryParser {

	@Inject
	private QueryAnalyzer analyzer;

	@Inject
	@Named("DefaultField")
	private String defaultField;

	public QueryInfo parseQuery(String queryString) {
		return parseQuery(defaultField, queryString, null);
	}

	public QueryInfo parseQuery(String field, String queryString, List<Token> toks) {
		if (queryString == null) {
			return null;
		}
		if (toks == null) {
			toks = new ArrayList<Token>();
		}
		List<Term> terms = new ArrayList<Term>();
		TokenStream stream = analyzer.tokenStream(null, new StringReader(queryString));
		Token token;
		try {
			while ((token = stream.next()) != null) {
				toks.add(token);
				terms.add(new Term(field, token.termText()));
			}
			stream.close();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		if (terms.size() < 1) {
			return null;
		} else {
			BooleanQuery query = new BooleanQuery();
			for (Term term : terms) {
				query.add(new TermQuery(term), BooleanClause.Occur.MUST);
			}
			return new QueryInfoImpl(query, toks);
		}
	}

}
